package com.ocm.tourism.core.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.TableGenerator;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.security.core.GrantedAuthority;

import com.ocm.tourism.core.model.UserInfo;

@Entity
public class Participant {

   @NotNull
   @NotEmpty
   @Size(max = 24)
   private String username;

   @NotNull
   @NotEmpty
   @Size(max = 24)
   private String password;

   @NotNull
   @NotEmpty
   @Size(max = 50)
   private String displayName;

   @Size(max = 255)
   private String address;

   @Size(max = 10)
   private String mobilephone;

   @Size(max = 15)
   private String homephone;

   @Size(max = 50)
   private String email;

   private Integer gender;

   @OneToMany(mappedBy = "participant", cascade = CascadeType.ALL, orphanRemoval = true)
   private List<Business> businesses;

   @OneToOne(cascade = CascadeType.ALL)
   private FileInfo avatar;

   private Boolean active;

   @OneToMany(mappedBy = "participant", cascade = CascadeType.ALL, orphanRemoval = true)
   private List<SecurityRole> securityRoles = new ArrayList<SecurityRole>();

   public String toString() {
      return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
   }

   public String getUsername() {
      return this.username;
   }

   public void setUsername(String username) {
      this.username = username;
   }

   public String getPassword() {
      return this.password;
   }

   public void setPassword(String password) {
      this.password = password;
   }

   public String getDisplayName() {
      return this.displayName;
   }

   public void setDisplayName(String displayName) {
      this.displayName = displayName;
   }

   public String getAddress() {
      return this.address;
   }

   public void setAddress(String address) {
      this.address = address;
   }

   public String getMobilephone() {
      return this.mobilephone;
   }

   public void setMobilephone(String mobilephone) {
      this.mobilephone = mobilephone;
   }

   public String getHomephone() {
      return this.homephone;
   }

   public void setHomephone(String homephone) {
      this.homephone = homephone;
   }

   public String getEmail() {
      return this.email;
   }

   public void setEmail(String email) {
      this.email = email;
   }

   public Integer getGender() {
      return this.gender;
   }

   public void setGender(Integer gender) {
      this.gender = gender;
   }

   public List<Business> getBusinesses() {
      return businesses;
   }

   public void setBusinesses(List<Business> businesses) {
      this.businesses = businesses;
   }

   public List<SecurityRole> getSecurityRoles() {
      return securityRoles;
   }

   public void setSecurityRoles(List<SecurityRole> securityRoles) {
      this.securityRoles = securityRoles;
   }

   @Id
   @GeneratedValue(strategy=GenerationType.TABLE,generator="GEN_PARTICIPANT")
   @TableGenerator(name = "GEN_PARTICIPANT", table = "SEQUENCE_LIST", allocationSize = 1, initialValue = 1, pkColumnName = "NAME", valueColumnName = "NEXT_SEQUENCE", pkColumnValue = "PARTICIPANT")
   private Long id;

   @Version
   @Column(name = "version")
   private Integer version;

   public Long getId() {
      return this.id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public Integer getVersion() {
      return this.version;
   }

   public void setVersion(Integer version) {
      this.version = version;
   }

   public FileInfo getAvatar() {
      return avatar;
   }

   public void setAvatar(FileInfo avatar) {
      this.avatar = avatar;
   }

   public Boolean getActive() {
      return active;
   }

   public void setActive(Boolean active) {
      this.active = active;
   }

   public void addSecuirtyRoles(SecurityRole securityRole){
      this.securityRoles.size();
      securityRole.setParticipant(this);
      this.securityRoles.add(securityRole);
   }

   @SuppressWarnings("serial")
   public UserInfo convertToUserInfo() {
      UserInfo userInfo = new UserInfo();
      userInfo.setAccountNonExpired(true);
      userInfo.setAccountNonLocked(this.active);
      userInfo.setCredentialsNonExpired(true);
      userInfo.setEnabled(this.active);
      Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
      if (this.securityRoles != null && this.securityRoles.size() > 0){
         for (SecurityRole securityRole : this.securityRoles){
            grantedAuthorities.add(securityRole);
         }
      }else {
         grantedAuthorities.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
               return RoleType.ROLE_USER.name();
            }
         });
      }
      userInfo.setGrantedAuthorities(grantedAuthorities);
      userInfo.setPassword(this.password);
      userInfo.setUsername(this.username);
      userInfo.setParticipantId(this.id);
      userInfo.setDisplayName(this.displayName);
      userInfo.setAvatarId(this.avatar == null ? null : this.avatar.getId());
      return userInfo;
   }
}
